package com.wenjie.original.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.wenjie.original.entity.SysDbTable;
import com.wenjie.original.entity.table.SysDbEnumTableDef;
import com.wenjie.original.entity.table.SysDbFieldTableDef;
import com.wenjie.original.entity.table.SysDbTableTableDef;
import com.wenjie.original.entity.vo.SysDbTable.SysDbTableUpOrAddVo;
import com.wenjie.original.entity.vo.SysDbTable.SysDbTableVo;
import com.wenjie.original.flex_config.baseInterface.Cus_ServiceImp;
import com.wenjie.original.mapper.SysDbTableMapper;
import com.wenjie.original.service.ISysDbEnumService;
import com.wenjie.original.service.ISysDbFieldService;
import com.wenjie.original.service.ISysDbTableService;
import com.wenjie.service.IGenService;
import com.wenjie.vo.gen.TableInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 表映射 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-09-06 15:29:29
 */
@Service
public class SysDbTableServiceImpl extends Cus_ServiceImp<SysDbTableMapper, SysDbTable> implements ISysDbTableService {


    @Autowired
    private IGenService genService;

    @Autowired
    private ISysDbEnumService sysDbEnumService;

    @Autowired
    private ISysDbFieldService sysDbFieldService;


    @Override
    public List<SysDbTableVo.ResVo> cusListAll() {

        List<SysDbTableVo.ResVo> matchs = new ArrayList<>(); // sysdbtbale匹配的数据
        List<SysDbTableVo.ResVo> tables = new ArrayList<>(); // sysdbtbale没有匹配的数据
        List<SysDbTableVo.ResVo> realDb = new ArrayList<>(); // 当前真实数据库没有匹配的数据


        // 记录的全部表信息
        List<SysDbTable> list = this.list();
        List<SysDbTableVo.ResVo> rests = new ArrayList<>();
        for (SysDbTable sysDbTable : list) {
            SysDbTableVo.ResVo bean = BeanUtil.toBean(sysDbTable, SysDbTableVo.ResVo.class);
            bean.setType("记录");
            rests.add(bean);
        }

        // 查看一下数据库的全部表信息
        List<TableInfo> realTableInfos = genService.getTables().getList();

        // 查看一下sysdbtbale中 匹配到和没匹配到的信息
        Set<String> tableNameSet = new HashSet<>();
        outerLoop:
        for (SysDbTableVo.ResVo rest : rests) {
            String tableName = rest.getTableName();
            for (TableInfo tableInfo : realTableInfos) {
                if (tableInfo.getName().equals(tableName)) {
                    rest.setIsMatch(true);
                    rest.setDbComment(tableInfo.getComment());
                    matchs.add(rest);
                    tableNameSet.add(tableName);
                    continue outerLoop;
                }
            }
            rest.setIsMatch(false);
            tables.add(rest);
        }

        // 查看一下没有匹配到的真实表信息
        for (TableInfo realTableInfo : realTableInfos) {
            if (!tableNameSet.contains(realTableInfo.getName())) {
                SysDbTableVo.ResVo resVo = new SysDbTableVo.ResVo();
                resVo.setTableName(realTableInfo.getName());
                resVo.setDbComment(realTableInfo.getComment());
                resVo.setIsMatch(false);
                resVo.setType("真实表");
                realDb.add(resVo);
            }
        }

        matchs.addAll(tables);
        matchs.addAll(realDb);
        return matchs;
    }

    @Override
    public void sync(String tableName) {

        // 查看一下数据库的全部表信息
        List<TableInfo> realTableInfos = genService.getTables().getList();
        List<TableInfo> collect = realTableInfos.stream().filter(s -> s.getName().equals(tableName)).collect(Collectors.toList());
        sync(tableName, collect);

    }

    private void sync(String tableName, List<TableInfo> collect) {
        try {
            SysDbTable sysDbTable = this.getByTableName(tableName);

            if (collect.size() == 0) {
                // 什么也不管
            } else {
                sysDbTable.setComment(collect.get(0).getComment());
                this.updateById(sysDbTable);
            }
        } catch (Exception e) {
            if (collect.size() == 0) {
                throw new RuntimeException("传参不正确");
            } else {
                TableInfo tableInfo = collect.get(0);
                SysDbTable sysDbTable = new SysDbTable();
                sysDbTable.setTableName(tableInfo.getName());
                sysDbTable.setComment(tableInfo.getComment());
                this.save(sysDbTable);
            }
        }
    }


    @Override
    public SysDbTable getByTableName(String tableName) {
        return this.getOne(QueryWrapper.create().where(SysDbTableTableDef.SYS_DB_TABLE.TABLE_NAME.eq(tableName)));
    }

    @Override
    public void syncAll() {
        // 查看一下数据库的全部表信息
        List<TableInfo> realTableInfos = genService.getTables().getList();

        for (TableInfo realTableInfo : realTableInfos) {

            List<TableInfo> TableInfos = new ArrayList<>();
            TableInfos.add(realTableInfo);
            sync(realTableInfo.getName(), TableInfos);
        }
    }

    @Override
    public void syncAllAndField() {
        // 同步表信息
        syncAll();

        // 同步全部的字典信息
        List<SysDbTable> list = this.list();
        for (SysDbTable sysDbTable : list) {
            sysDbFieldService.syncAll(sysDbTable.getSysDbTableId());
        }
    }

    @Override
    public void custUpdateById(SysDbTableUpOrAddVo.UpVo upVo) {
        sysDbEnumService.updateChain().set(SysDbEnumTableDef.SYS_DB_ENUM.TABLE_NAME, upVo.getTableName()).where(SysDbEnumTableDef.SYS_DB_ENUM.SYS_DB_TABLE_ID.eq(upVo.getSysDbTableId())).update();
        this.updateById(upVo);
    }

    @Override
    public void cusRemoveByid(Long id) {

        // 删除字段信息
        sysDbFieldService.remove(QueryWrapper.create().where(SysDbFieldTableDef.SYS_DB_FIELD.SYS_DB_TABLE_ID.eq(id)));

        // 删除枚举信息
        sysDbEnumService.remove(QueryWrapper.create().where(SysDbEnumTableDef.SYS_DB_ENUM.SYS_DB_TABLE_ID.eq(id)));

        // 删除表信息
        this.removeById(id);
    }


}
